package com.bearingnavi.android.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import android.net.Uri;

import com.bearingnavi.android.overlays.WalkingPathOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class OverlayResolver {

	private static Logger log = Logger.getLogger(OverlayResolver.class);
	
	public static List<Overlay> getOverlays(Uri data, String filePath, boolean loadLastState, MapView mapView) {
		List<Overlay> overlays = null;
		
		if (loadLastState) {
			overlays = StateSaver.getInstance().getSavedOverlays();
		} else {
			overlays = new ArrayList<Overlay>();
		}
		
		if (data != null) {
			try {
				if (data.getHost() != null && data.getHost().equals("bearingnavi.com")) {//Is url data.

					overlays.addAll(overlayFactory(
							URLDecoder.decode(data.getPathSegments().get(0), "utf-8"), false, mapView));
				} else {//Is file data.

					overlays.addAll(overlayFactory(getFileContent(data), false, mapView));
				}
				
			} catch (UnsupportedEncodingException e) {
				log.error(e, e);
			}
		}
		if (filePath != null) {
			overlays.addAll(
					overlayFactory(
							StateSaver.getInstance().getFileContent(filePath), false, mapView));
		}
		
		return mergeWalkingPathOverlayWithMap(overlays, mapView);
	}
	
	private static String getFileContent(Uri data) {
		if (data.getScheme().equals("file")) {
			return StateSaver.getInstance().getFileContent(data.toString().replace("file://", ""));
		}
		return null;
	}
	
	private static List<Overlay> mergeWalkingPathOverlayWithMap(List<Overlay> overlays, MapView mapView) {
		WalkingPathOverlay walkingPathOverlay = getWalkingPathOverlay(mapView);
		
		Iterator<Overlay> iterator = overlays.iterator();
		while (iterator.hasNext()) {
			Overlay overlay = (Overlay) iterator.next();
			if (overlay instanceof WalkingPathOverlay) {
				walkingPathOverlay.merge((WalkingPathOverlay) overlay);
				iterator.remove();
			}
		}
		
		return overlays;
	}
	
	public static List<Overlay> overlayFactory(String marshalledData, boolean createAsSnapshot, MapView mapView) {
		String[] marshalledObjects = marshalledData.split(MarshalOverlay.OBJECTS_SEPARATOR);
		List<Overlay> overlays = new ArrayList<Overlay>();
		for (String objectData : marshalledObjects) {
			
			String[] objectFields = objectData.split(MarshalOverlay.FIELDS_SEPARATOR);
			String className = objectFields[0];
			
			try {
				Overlay overlay = (Overlay) Class.forName(className).newInstance();
				((MarshalOverlay)overlay).unmarshal(objectFields, createAsSnapshot, mapView);
				overlays.add(overlay);
				
			} catch (Exception e) {
				log.error(e, e);
			}
		}
		return overlays;
	}
	
	private static WalkingPathOverlay getWalkingPathOverlay(MapView mapView) {
		for (Overlay overlay : mapView.getOverlays()) {
			if (overlay instanceof WalkingPathOverlay) {
				return (WalkingPathOverlay) overlay;
			}
		}
		return null;
	}
}
